package san.java.day13;

import org.apache.commons.lang3.time.StopWatch;

import java.io.*;


/**
 * 缓冲流:
 *  1. 为了提高数据读写的速度,Java API内部提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组
 *  2. 先把数据缓冲到内存里,在内存中去做IO操作,基于内存的IO比基于硬盘的IO快75000多倍
 *  3. 缓冲流要套接在相应的节点流之上, 对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
 *  4. 对于输出的缓冲流,写出的数据会在内存中缓存,使用flush()将会使内存中的数据立刻写出
 *
 *  缓冲字节流:
 *      BufferedInputStream BufferedOutputStream
 *  缓冲字符流:
 *      BufferedReader 和 BufferedWriter
 *
 *  关闭流的顺序, 本着一个最晚开的最早关, 依次关闭
 *
 *
 *
 */

public class BufferByteStream_01 {

    public static void testBufferedStream() throws IOException {

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 文件字节输入流对象
        FileInputStream in = new FileInputStream("data/a1.txt");
        FileOutputStream out = new FileOutputStream("data/a4.txt");

        // 缓冲字节流对象
        BufferedInputStream bin = new BufferedInputStream(in);
        BufferedOutputStream bout = new BufferedOutputStream(out);

        byte[] b = new byte[4096];

        int len = 0;
        while ((len = bin.read(b)) != -1) {
            bout.write(b, 0, len);
        }
        bout.flush();

        bout.close();
        bin.close();
        out.close();
        in.close();

        stopWatch.stop();

        System.out.println("Time Elapsed: " + stopWatch.getTime() + "ms");
    }

    /**
     * 测试不带缓冲区的耗时
     */
    public static void testFileStream() throws IOException{
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 文件字节输入流对象
        FileInputStream in = new FileInputStream("data/a1.txt");
        FileOutputStream out = new FileOutputStream("data/a4.txt");

        byte[] b = new byte[4096];

        int len = 0;
        while ((len = in.read(b)) != -1) {
            out.write(b, 0, len);
        }
        out.flush();

        out.close();
        in.close();

        stopWatch.stop();

        System.out.println("Time Elapsed: " + stopWatch.getTime() + "ms");
    }

    public static void main(String[] args) {
        try {
            testBufferedStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            testFileStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
